﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Mailer.Model.Repositories;
using System.Text.RegularExpressions;
using NHibernate;
using Mailer.Model;
using Mailer.Model.Types;
using System.Net.Mail;
using System.IO;
using NHibernate.Criterion;

namespace Mailer.Controllers
{
	[HandleError]
	public class ListController : Controller
	{
		[Authorize]
		public ActionResult View(Guid id, string q)
		{
			// kolla access


			ISession sess = SessionUtilities.BeginSession();
			if (sess != null)
			{
				List list = sess.Get<List>(id);

				ViewData["ID"] = list.ID;
				ViewData["ApplicationID"] = list.ApplicationID;
				ViewData["Name"] = list.Name;
				ViewData["ShortName"] = list.ShortName;

				ViewData["Recipients"] = sess.CreateQuery("select r from List as l inner join l.Recipients as r where l.ID = :list and r.Email like :q")
					.SetParameter("q", "%" + q + "%")
					.SetParameter("list", list.ID)
					.SetMaxResults(50)
					.List<Recipient>();

				// ViewData["Recipients"] = sess.CreateSQLQuery("select r.* from Recipients r inner join ListRecipients lr on r.ID = lr.RecipientID and lr.ListID = :list and r.Email like :q").SetParameter("q", "%" + q + "%").SetParameter("list", list.ID).List();

				// ViewData["Recipients"] = sess.CreateCriteria<Recipient>().Add(Expression.Eq("Lists", list)).List<Recipient>();

				//	ViewData["Recipients"] = list.Recipients;

				ViewData["Mails"] = list.Mails;
				ViewData["q"] = q;

				SessionUtilities.EndSession(sess);
			}
			return base.View();
		}



		[Authorize]
		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult New()
		{
			return base.View();
		}

		[Authorize]
		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult New(string name, string shortname, bool ispublic)
		{
			ActionResult res = null;

			Guid userid = Utilities.GetUserID(this);

			if (name.Length < 5)
			{
				ModelState.AddModelError("_FORM", "Name should be 5 characters or more.");
			}
			else if (shortname.Length < 5)
			{
				ModelState.AddModelError("_FORM", "Shortname should be 5 characters or more.");
			}
			else if (Regex.IsMatch("[^a-z0-9]", shortname))
			{
				ModelState.AddModelError("_FORM", "Shortname can only contain the characters: a-z and 0-9.");
			}
			else
			{
				// TODO: Check for duplicate shortnames!

				ISession sess = SessionUtilities.BeginSession();
				if (sess != null)
				{
					Guid appid = new Guid(Request["application"]);
					Guid listid = Guid.Empty;

					using (ITransaction transaction = sess.BeginTransaction())
					{
						List newlist = new List();
						newlist.Name = name;
						newlist.ShortName = shortname;
						newlist.ApplicationID = appid;
						newlist.CreatedBy = userid;
						newlist.UpdatedBy = userid;
						newlist.CreatedDate = DateTime.Now;
						newlist.UpdatedDate = DateTime.Now;
						newlist.IsPublic = ispublic;
						sess.Save(newlist);
						// listid = newlist.ID;

						Application app = sess.Get<Application>(appid);
						app.Lists.Add(newlist);
						sess.Save(app);

						res = RedirectToAction("View", "List", new { ID = newlist.ID });

						transaction.Commit();
					}

					SessionUtilities.EndSession(sess);
				}
			}

			if (res == null)
				res = View();
			return res;
		}


		[Authorize]
		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult Edit(Guid id)
		{
			ISession sess = SessionUtilities.BeginSession();
			if (sess != null)
			{
				List list = sess.Get<List>(id);
				if (list != null)
				{
					ViewData["ID"] = list.ID;
					ViewData["ApplicationID"] = list.ApplicationID;
					ViewData["Name"] = list.Name;
					ViewData["ShortName"] = list.ShortName;
					ViewData["IsPublic"] = list.IsPublic;
				}

				SessionUtilities.EndSession(sess);
			}

			return base.View();
		}

		[Authorize]
		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Edit(Guid id, string name, string shortname, bool ispublic)
		{
			ActionResult res = null;

			Guid userid = Utilities.GetUserID(this);

			if (name.Length < 5)
			{
				ModelState.AddModelError("_FORM", "Name should be 5 characters or more.");
			}
			else if (shortname.Length < 5)
			{
				ModelState.AddModelError("_FORM", "Shortname should be 5 characters or more.");
			}
			else if (Regex.IsMatch("[^a-z0-9]", shortname))
			{
				ModelState.AddModelError("_FORM", "Shortname can only contain the characters: a-z and 0-9.");
			}
			else
			{
				// TODO: Check for duplicate shortnames!

				ISession sess = SessionUtilities.BeginSession();
				if (sess != null)
				{
					List list = sess.Get<List>(id);
					if (list != null)
					{
						using (ITransaction transaction = sess.BeginTransaction())
						{
							list.Name = name;
							list.ShortName = shortname;
							list.UpdatedBy = userid;
							list.UpdatedDate = DateTime.Now;
							list.IsPublic = ispublic;
							sess.Save(list);

							res = RedirectToAction("View", "List", new { ID = list.ID });
							transaction.Commit();
						}
					}

					SessionUtilities.EndSession(sess);
				}
			}

			if (res == null)
				res = View();
			return res;
		}



		[Authorize]
		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult Clear(Guid id)
		{
			ISession sess = SessionUtilities.BeginSession();
			if (sess != null)
			{
				List listobj = sess.Get<List>(id);
				if (listobj != null)
				{
					Application app = sess.Get<Application>(listobj.ApplicationID);
					if (app != null)
					{
						using (ITransaction transaction = sess.BeginTransaction())
						{
							//					for( int j=listobj.Recipients.Count-1; j>=0; j-- )
							//						listobj.Recipients.RemoveAt(j);

							//	sess.CreateQuery("delete r from List as l inner join l.Recipient r where l.ID = :list")
							//		.SetParameter("list", listobj.ID)
							//		.ExecuteUpdate();

							listobj.Recipients.Clear();

							sess.Save(listobj);

							transaction.Commit();

							TempData["message"] = "All recipients was removed from the list";
						}
					}
				}

				SessionUtilities.EndSession(sess);
			}

			return RedirectToAction("View", "List", new { ID = id });
		}






		[Authorize]
		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Import(Guid list, string format, bool? force)
		{
			ISession sess = SessionUtilities.BeginSession();
			if (sess != null)
			{
				List listobj = sess.Get<List>(list);
				Application app = sess.Get<Application>(listobj.ApplicationID);
				List<string> emails = new List<string>();

				using (ITransaction transaction = sess.BeginTransaction())
				{
					foreach (string inputTagName in Request.Files)
					{
						var file = Request.Files[inputTagName];
						int numadded = 0;
						int numfound = 0;
						listobj.AddRecipientsFromFile(sess, transaction, file.InputStream, format, force.HasValue ? force.Value : false, out numfound, out numadded);

						transaction.Commit();

						TempData["message"] = numadded + " new adresses were added (" + (numfound - numadded) + " duplicates) out of " + numfound + " found adresses found in file";
					}
				}

				SessionUtilities.EndSession(sess);
			}

			return RedirectToAction("View", "List", new { ID = list });
		}



		[Authorize]
		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult Export(Guid list, string format)
		{
			ISession sess = SessionUtilities.BeginSession();
			if (sess != null)
			{
				List listobj = sess.Get<List>(list);
				Application app = sess.Get<Application>(listobj.ApplicationID);

				switch (format)
				{
					default:
					case "enter":
						Response.AddHeader("Content-disposition", "attachment; filename=\"" + listobj.Name + ".txt\"");
						Response.ContentType = "text/plain";
						break;

					case "tsv":
						Response.AddHeader("Content-disposition", "attachment; filename=\"" + listobj.Name + ".tab.txt\"");
						Response.ContentType = "text/plain";
						break;

					case "csv":
						Response.AddHeader("Content-disposition", "attachment; filename=\"" + listobj.Name + ".csv.txt\"");
						Response.ContentType = "text/plain";
						break;
				}

				bool first = true;
				foreach (Recipient r in listobj.Recipients)
				{
					if (!first)
					{
						switch (format)
						{
							default:
							case "enter":
								Response.Write("\r\n");
								break;

							case "tsv":
								Response.Write("\t");
								break;

							case "csv":
								Response.Write(",");
								break;
						}
					}

					Response.Write(r.Email);
					first = false;
				}

				SessionUtilities.EndSession(sess);

				Response.End();
			}

			return null;// RedirectToAction("View", "List", new { ID = list });
		}

	}
}
